package com.sname.car.user.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sname.car.cache.CommonCacheUtil;
import com.sname.car.common.QiNiuFileUploadUtil;
import com.sname.car.common.RandomNumberCoder;
import com.sname.car.common.constants.Constants;
import com.sname.car.common.exception.CarException;
import com.sname.car.jms.SmsProcessor;
import com.sname.car.security.AESUtil;
import com.sname.car.security.Base64Util;
import com.sname.car.security.RSAUtil;
import com.sname.car.user.dao.UserMapper;
import com.sname.car.user.entity.User;
import com.sname.car.user.entity.UserElement;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
/**
 * Created By  醉美柳舞之众星捧月
 * @author songx
 * @date 2018/9/21 22:22
 */
@Service
public class UserServiceImpl implements UserService {
    private Logger log = LoggerFactory.getLogger(getClass());
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SmsProcessor smsProcessor;
    @Autowired
    private CommonCacheUtil cacheUtil;
    @Override
    public String login(String loginData, String loginKey) {
        String token = null;
        try {
            /** RSA 解密 **/
            byte[] RSAResult = RSAUtil.decryptByPrivateKey(Base64Util.decode(loginKey));
            /** AES 解密 **/
            String AESResult = AESUtil.decrypt(new String(RSAResult, "utf-8"));
            if (StringUtils.isBlank(AESResult)) {
                throw new Exception("解析密钥失败！");
            }
            /** 解析从手机端加密过来的对象 **/
            JSONObject jsonObject = JSON.parseObject(AESResult);
            String platform = jsonObject.getString("platform");
            String mobile = jsonObject.getString("mobile");
            String code = jsonObject.getString("code");
            if (StringUtils.isBlank(platform) || StringUtils.isBlank(mobile) || StringUtils.isBlank(code)) {
                throw new Exception("登陆传输加密失败,请重新登录！");
            }
            /** 判断验证码是否正确 **/
            String cacheValue = cacheUtil.getCacheValue(mobile);
            if (!code.equals(cacheValue) || StringUtils.isBlank(cacheValue)) {
                throw new Exception("验证码匹配失败！");
            }
            User user = userMapper.selectByMobile(mobile);
            /** 如果查无此人,就自动注册 **/
            if (org.springframework.util.StringUtils.isEmpty(user) || user == null) {
                try {
                    user = new User();
                    user.setMobile(mobile);
                    user.setNickname(mobile);
                    userMapper.insertSelective(user);
                } catch (Exception e) {
                    throw new CarException("自动注册用户失败！");
                }
            }
            /** 如果前面都不报错,那么就可以登录并生成token **/
            try {
                token = generateToken(user);
                UserElement userElement = new UserElement();
                userElement.setMobild(mobile);
                userElement.setToken(token);
                userElement.setPlatform(platform);
                userElement.setUserId(user.getId());
                if (cacheUtil.putTokenWhenLogin(userElement)) {
                    throw new CarException("缓存用户token失败！");
                }
            } catch (Exception e) {
                log.error("Fail to cache to redis", e);
            }
        } catch (Exception e) {
            log.error("Fail to login", e);

        }
        return token;
    }
    @Override
    public int modifyNickName(User user) {
        return userMapper.updateByPrimaryKeySelective(user);
    }
    @Override
    public Boolean sengVerCode(String mobile, String ip) throws Exception {
        String verCode = RandomNumberCoder.verCode();
        /** 在redis中查看是否 有效期内重复请求  或者  这个 ip 重复请求很多次 **/
        int result = cacheUtil.cacheForVerificationCode(Constants.VERIFYCODE_PREFIX + mobile, verCode, "reg", 60, ip);
        if (result == 1) {
            log.info("当前验证码未过期，请稍后重试");
            throw new CarException("当前验证码未过期，请稍后重试");
        } else if (result == 2) {
            log.info("超过当日验证码次数上线");
            throw new CarException("超过当日验证码次数上限");
        } else if (result == 3) {
            log.info("超过当日验证码次数上限 {}", ip);
            throw new CarException(ip + "超过当日验证码次数上限");
        }
        log.info("Sending verify code {} for phone {}", verCode, mobile);

        /** 将验证码推送到消息队列 **/
        ActiveMQQueue queue = new ActiveMQQueue();
        HashMap<String, String> map = new HashMap<>();
        map.put("mobile", mobile);
        map.put("tplId", Constants.MDSMS_VERCODE_TPLID);
        map.put("verCode", verCode);
        String message = JSON.toJSONString(map);
        smsProcessor.sendSmsToQuery(queue, message);
        return true;
    }
    @Override
    public String uploadUserImg(MultipartFile file, Long userId) throws CarException {
        String imgUrl;
        try {
            /** 找到要修改头像的这个人 **/
            User user = userMapper.selectByPrimaryKey(userId);
            /** 上传头像,返回得到文件的url **/
            imgUrl = QiNiuFileUploadUtil.uploadImg(file);
            /** 更新这个用户的头像(地址) **/
            user.setHeadImg(imgUrl);
            userMapper.insertSelective(user);
        } catch (Exception e) {
            log.error("Fail to upload user Head Img", e);
            throw new CarException("上传头像失败！");
        }
        return Constants.QINIU_HEAD_IMG_BUCKET_URL + "/" + Constants.QINIU_HEAD_IMG_BUCKET_NAME + "/" + imgUrl;
    }
    /** 生成Token **/
    private String generateToken(User user) {
        return user.getId() + ":" + user.getMobile() + ":" + System.currentTimeMillis();
    }
}
